今天是第二十七天我們可以寫一個k8s海關資料庫管理系統,以下是我的程式碼
這裡我們將使用 React.js 來構建前端界面,它將與後端 API 進行交互:
npx create-react-app customs-management-system
cd customs-management-system
npm install axios
在 App.js
中:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [customsData, setCustomsData] = useState([]);
const [newEntry, setNewEntry] = useState({});
useEffect(() => {
fetchData();
}, []);
const fetchData = async () => {
const result = await axios.get('/api/customs');
setCustomsData(result.data);
};
const handleInputChange = (e) => {
const { name, value } = e.target;
setNewEntry({ ...newEntry, [name]: value });
};
const handleSubmit = async (e) => {
e.preventDefault();
await axios.post('/api/customs', newEntry);
fetchData();
};
return (
<div>
<h1>海關資料管理系統</h1>
<form onSubmit={handleSubmit}>
<input name="name" placeholder="名稱" onChange={handleInputChange} />
<input name="description" placeholder="描述" onChange={handleInputChange} />
<button type="submit">新增資料</button>
</form>
<h2>資料列表</h2>
<ul>
{customsData.map((entry) => (
<li key={entry.id}>{entry.name}: {entry.description}</li>
))}
</ul>
</div>
);
}
export default App;
建立 Node.js 後端應用來處理業務邏輯,並與資料庫進行交互:
mkdir backend
cd backend
npm init -y
npm install express mongoose
在 index.js
中:
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
mongoose.connect('mongodb://mongo:27017/customs', { useNewUrlParser: true, useUnifiedTopology: true });
const customsSchema = new mongoose.Schema({
name: String,
description: String,
});
const Customs = mongoose.model('Customs', customsSchema);
app.get('/api/customs', async (req, res) => {
const customs = await Customs.find();
res.send(customs);
});
app.post('/api/customs', async (req, res) => {
const newCustom = new Customs(req.body);
await newCustom.save();
res.send(newCustom);
});
app.listen(3001, () => {
console.log('API 伺服器運行在 3001 端口');
});
Kubernetes 上可以部署 MongoDB。首先,撰寫一個 MongoDB 的 K8s 部署 YAML 檔案:
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
persistentVolumeClaim:
claimName: mongo-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mongo
spec:
ports:
- port: 27017
selector:
app: mongo
接著,定義 PersistentVolumeClaim (PVC) 來儲存 MongoDB 資料:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
我們可以將 React 應用、Node.js API 伺服器以及 MongoDB 部署到 Kubernetes 集群。
撰寫 API 的 Kubernetes 部署檔案:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
spec:
replicas: 1
selector:
matchLabels:
app: backend-api
template:
metadata:
labels:
app: backend-api
spec:
containers:
- name: backend-api
image: your-backend-api-image # 在 Docker Hub 上推送你的後端 API 圖像
ports:
- containerPort: 3001
env:
- name: MONGO_URL
value: "mongodb://mongo:27017/customs"
---
apiVersion: v1
kind: Service
metadata:
name: backend-api
spec:
ports:
- port: 3001
selector:
app: backend-api
將前端部署為一個 Kubernetes 服務:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: your-frontend-image # 在 Docker Hub 上推送你的前端 React 應用圖像
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
ports:
- port: 80
selector:
app: frontend
type: LoadBalancer
使用 Helm 來打包你的應用程式可以簡化部署流程。可以將 MongoDB、前端和後端配置為 Helm chart,讓整個應用的部署變得更加自動化和一致性。
這部分的程式碼負責建立一個簡單的前端應用,讓使用者可以輸入、查看和新增海關資料。這裡使用 React.js 框架和 axios
來進行前後端 API 的交互。
useState
和 useEffect
:const [customsData, setCustomsData] = useState([]);
const [newEntry, setNewEntry] = useState({});
這裡 useState
用來定義兩個狀態變數:
customsData
:儲存從後端 API 獲取的海關資料列表。newEntry
:儲存使用者輸入的新資料。useEffect(() => {
fetchData();
}, []);
useEffect
會在元件渲染後執行一次,用來觸發 fetchData()
函數來獲取資料。
fetchData
函數:const fetchData = async () => {
const result = await axios.get('/api/customs');
setCustomsData(result.data);
};
這個函數會向後端 API 發送 GET
請求,從 /api/customs
端點取得海關資料,然後將結果保存到 customsData
中。
handleInputChange
函數:const handleInputChange = (e) => {
const { name, value } = e.target;
setNewEntry({ ...newEntry, [name]: value });
};
這個函數會在使用者輸入資料時更新 newEntry
,使新資料能夠被即時反映出來。e.target
代表當前的輸入框,name
和 value
代表這個輸入框的名稱和值。
handleSubmit
函數:const handleSubmit = async (e) => {
e.preventDefault();
await axios.post('/api/customs', newEntry);
fetchData();
};
當使用者提交表單時,這個函數會被觸發。它會向後端 API 發送一個 POST
請求,將使用者輸入的 newEntry
資料發送到伺服器,並重新呼叫 fetchData()
以更新顯示的資料。
<ul>
{customsData.map((entry) => (
<li key={entry.id}>{entry.name}: {entry.description}</li>
))}
</ul>
這段程式碼會渲染一個列表,顯示從後端 API 獲取的所有海關資料。
這部分的程式碼負責處理資料庫邏輯,使用 Express 框架來建立後端伺服器,並且透過 MongoDB 來儲存和讀取海關資料。
mongoose.connect('mongodb://mongo:27017/customs', { useNewUrlParser: true, useUnifiedTopology: true });
這裡使用 mongoose
來連接 MongoDB 資料庫,mongodb://mongo:27017/customs
是資料庫的連接字串,mongo
是在 Kubernetes 中部署的 MongoDB 服務的名稱。
const customsSchema = new mongoose.Schema({
name: String,
description: String,
});
mongoose.Schema
定義了一個名為 customsSchema
的模式,表示每筆海關資料都包含 name
和 description
兩個欄位,型別皆為 String
。
const Customs = mongoose.model('Customs', customsSchema);
這裡創建了名為 Customs
的模型,這是基於我們定義的 customsSchema
,它將用來與 MongoDB 進行操作。
app.get('/api/customs', async (req, res) => {
const customs = await Customs.find();
res.send(customs);
});
這段程式碼建立了一個 /api/customs
端點,當前端向這個端點發送 GET
請求時,後端會從資料庫中讀取所有的海關資料並將其返回給前端。
app.post('/api/customs', async (req, res) => {
const newCustom = new Customs(req.body);
await newCustom.save();
res.send(newCustom);
});
這裡建立了一個 POST
端點,當前端向這個端點發送新的海關資料時,後端會將資料保存到資料庫並返回保存後的資料。
app.listen(3001, () => {
console.log('API 伺服器運行在 3001 端口');
});
這行程式碼會啟動後端伺服器並監聽 3001 端口,當 API 收到請求時,它會進行相應的處理。
這部分程式碼負責將 MongoDB 部署到 Kubernetes,MongoDB 將用來存儲所有的海關資料。
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo
ports:
- containerPort: 27017
volumeMounts:
- name: mongo-storage
mountPath: /data/db
volumes:
- name: mongo-storage
persistentVolumeClaim:
claimName: mongo-pvc
這裡定義了 MongoDB 在 Kubernetes 上的部署:
mongo
,使用了官方的 MongoDB Docker 映像。volumeMounts
和 volumes
定義了資料卷,確保 MongoDB 的資料是持久化的。apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mongo-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
這段程式碼定義了資料持久化卷 (PVC),確保 MongoDB 的資料存儲在一個 1GiB 的持久性磁碟中。
這部分負責將前端應用和後端 API 部署到 Kubernetes。
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-api
spec:
replicas: 1
selector:
matchLabels:
app: backend-api
template:
metadata:
labels:
app: backend-api
spec:
containers:
- name: backend-api
image: your-backend-api-image
ports:
- containerPort: 3001
env:
- name: MONGO_URL
value: "mongodb://mongo:27017/customs"
這裡部署了後端 API,使用了名為 your-backend-api-image
的 Docker 映像,並暴露 3001 端口。MONGO_URL
環境變數用來告知後端如何連接 MongoDB。
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 1
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: your-frontend-image
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: frontend
spec:
ports:
- port: 80
selector:
app: frontend
type: LoadBalancer
這裡部署了前端應用,使用名為 your-frontend-image
的 Docker 映像,並暴露 80 端口。Service
將這個應用設定為一個 LoadBalancer,使外部可以訪問。
這樣就完成了整個系統的部署和運行,你可以在 Kubernetes 集群中
運行前端、後端和 MongoDB,並且它們會協同工作來處理海關資料的管理和顯示。